#ifndef MOB_H_INCLUDED
#define MOB_H_INCLUDED

#include "Object.h"
#include "Controller.h"
#include "Cell.h"

#include <QDebug>

Direction randDirection();
Direction invertDirection( Direction d );
void operator++( Direction& d );
  // converts Cell to direction, used by controllers to make mobs move using paths found
Direction cellToDirection( Cell c, Mob* m );
//Directions operator++( Direction d, int );

  // base class for all mobs in game
class Mob : public Object
{
    public:
          // highest level a mob can reach
        static const int LEVELCAP = 90;

        Mob( int x_ = -1, int y_ = -1, Field* f_ = 0, bool status = true,
             Team team_ = TEAMENUM, Controller* control = 0, int MS = 0,
             int L = 0, bool alerted = false, bool isPlayer = false,
             bool timedLife = false, int timeTillDeath = 1,
             int shifts_ = 0, int lastUpdate_ = 0, int xp = 0,
             int sightRange_ = 0, int level_ = 1 )
                 :Object(x_, y_, f_, status), sightRange(sightRange_),
                  moveSpeed(MS), lifes(L), shifts(shifts_),
                  lastUpdate( lastUpdate_ ), experience(xp),
                  levelExp( 10 ), level(level_), timeTillDeath_(timeTillDeath),
                  isAlerted(alerted), isPlayer_(isPlayer),
                  timedLife_(timedLife), team(team_), controller(control)
        {
            controller->setMob( this );
        }
          // is called at time the mob is killed
        virtual void kill() = 0;

          // makes mob to preform some kind of attack action
        virtual void attack( Direction d ) = 0;
          // makes mob take some damage
        void damage( int value );
          // is used to level up
        virtual void levelUp() {}

        int getSightRange() const { return sightRange; }
        int getMoveSpeed() const { return moveSpeed; }
        int getLifes() const { return lifes; }
        int getShifts() const { return shifts; }
        int getLastUpdate() const { return lastUpdate; }
        int getXp() const { return experience; }
        int getTargetXp() const { return levelExp; }
        int getLevel() const { return level; }
        int timeTillDeath() const { return timeTillDeath_; }
        bool getAlert() const { return isAlerted; }
        bool isPlayer() const { return isPlayer_; }
        bool timedLife() const { return timedLife_; }
        Team getTeam() const { return team; }
        Controller* getController() const { return controller; }

        void setSightRange( int i ) { sightRange = i; }
        void setMoveSpeed( int i ) { moveSpeed = i; }
        void setLifes( int i ) { lifes = i; }
        void setShifts( int i ) { shifts = i; }
        void setLastUpdate( int i ) { lastUpdate = i; }
        void setXp( int i ) { experience = i; }
        void setTargetXp( int i ) { levelExp = i; }
        void setLevel( int i ) { level = i; }
        void setTimeTillDeath( int i ) { timeTillDeath_ = i; }
        void setAlert( bool i ) { isAlerted = i; }
        void setPlayerStatus( bool i ) { isPlayer_ = i; }
        void setTimedLifeStatus( bool i ) { timedLife_ = i; }
        void setTeam( Team i ) { team = i; }
        void setController( Controller* i ) { controller = i; }

        void earnXP( int i = 1 ) { experience += i; }
        void earnLevel( int i = 1 );
        void earnShift( int i = 1 ) { shifts += i; }
        void earnLife( int i = 1 ) { lifes += i; }
        void earnTime( int i = 1 ) { timeTillDeath_ += i; }

        void loseTime( int i = 1 ) { timeTillDeath_ -= i; }

        virtual ~Mob() { if( controller ) delete controller; }
    protected:
    private:
          // field of view
        int sightRange;
          // speed, with which the mob moves
        int moveSpeed;
          // number of mob's lifes
        int lifes;
          // nuber of shifts
        int shifts;
          // used to prevent multymoving at single update
        int lastUpdate;
          // more exp == more lifes
        int experience;
          // how much exp is required to advance a level
        int levelExp;
          // current level ( look at mob's levelUp function to see,
          // what does it change, also look at it's damage function,
          // it might affect the way mob takes damage )
        int level;
          // is used if timedLife is true,
          // postfix is used to fix name conflict with a getter function
        int timeTillDeath_;

          // true if mob is alrted
        bool isAlerted;
          // true if this mob is actually player,
          // postfix is used to fix name conflict with a getter function
        bool isPlayer_;
          // true, if mob has timed life
          //  postfix is used to fix name conflict with a getter function
        bool timedLife_;

          // team of a mob
        Team team;
          // brain of a mob
        Controller* controller;
};


#endif // MOB_H_INCLUDED
